package com.eaero.service.exit;

import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.eaero.CommonResp;
import com.eaero.controller.exit.pojo.TraceCreateToolExitRequest;
import com.eaero.controller.exit.pojo.TraceExitToolInfoVo;
import com.eaero.controller.exit.pojo.TraceToolExitInfoVo;
import com.eaero.entity.TraceExitRecord;
import com.eaero.entity.TraceExitRecordDetail;
import com.eaero.entity.TraceTool;
import com.eaero.entity.TraceUser;
import com.eaero.mapper.TraceExitRecordMapper;
import com.eaero.service.ITraceExitRecordDetailService;
import com.eaero.service.ITraceExitRecordService;
import com.eaero.service.ITraceToolService;
import com.eaero.service.ITraceUserService;
import com.eaero.util.IdGenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.hutool.core.util.ObjectUtil;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author luofeng
 * @since 2023-07-07
 */
@Service
public class TraceExitRecordServiceImpl extends ServiceImpl<TraceExitRecordMapper, TraceExitRecord> implements ITraceExitRecordService {

    @Autowired
    private ITraceUserService userService;

    @Autowired
    private ITraceToolService toolService;

    @Autowired
    private ITraceExitRecordDetailService recordDetailService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public CommonResp postGoTlReturn(TraceCreateToolExitRequest request) {

        TraceUser user = userService.getOne(Wrappers.<TraceUser>lambdaQuery()
                .eq(TraceUser::getUserCode, request.getUserCode()));

        if (ObjectUtil.isEmpty(user)) {
            return CommonResp.buildFailMsg("“生成退料单失败！员工号不存在");
        }

        List<TraceExitToolInfoVo> goReturn = request.getGoReturn();

        List<String> rids = goReturn.stream().map(TraceExitToolInfoVo::getRid).collect(Collectors.toList());

        List<TraceTool> tools = toolService.list(Wrappers.<TraceTool>lambdaQuery().in(TraceTool::getRid, rids));

        for (TraceTool tool : tools) {
            if ("在库".equals(tool.getTlStatus())) {
                return CommonResp.buildFailMsg(StrUtil.format("退料件号 {} 刻号 {} 不处于借出状态", tool.getPartno(), tool.getTrno()));
            }
        }

        List<TraceTool> parentTools = tools.stream().filter(item -> StrUtil.isEmpty(item.getParentPartno())).collect(Collectors.toList());

        Map<String, List<TraceTool>> groupBy = tools.stream()
                .filter(item -> StrUtil.isNotEmpty(item.getParentPartno()))
                .collect(Collectors.groupingBy(item -> item.getParentPartno() + item.getParentTrno()));

        for (TraceTool parentTool : parentTools) {
            if (StrUtil.isNotEmpty(parentTool.getParentPartno())) {
                long count = toolService.count(Wrappers.<TraceTool>lambdaQuery()
                        .eq(TraceTool::getParentPartno, parentTool.getParentPartno())
                        .eq(TraceTool::getParentTrno, parentTool.getParentTrno()));

                List<TraceTool> children = groupBy.get(parentTool.getParentPartno() + parentTool.getParentTrno());
                if (!NumberUtil.equals(children.size(), count)) {
                    return CommonResp.buildFailMsg(StrUtil.format("退料清单包含套装件 {} 刻号 {}，未包含其所有子件号", parentTool.getPartno(), parentTool.getTrno()));
                }
            }
        }

        TraceExitRecord exitRecord = new TraceExitRecord();
        exitRecord.setId(IdGenUtils.genId());
        exitRecord.setTrId(exitRecord.getId());
        exitRecord.setReturnPnum(IdGenUtils.genCode());
        exitRecord.setOrigin(request.getOrigin());
        exitRecord.setReturnRemark(request.getReturnRemark());
        exitRecord.setStatus("提交退料");
        exitRecord.setWarehouse(CollUtil.getFirst(tools).getWarehouse());
        exitRecord.setCreateUserCode(user.getUserCode());
        exitRecord.setCreateUserName(user.getUserName());
        exitRecord.setCreated(LocalDateTime.now());

        List<TraceExitRecordDetail> exitRecordDetails = new ArrayList<>();
        Map<String, TraceTool> tool2Rid = CollStreamUtil.toMap(tools, TraceTool::getRid, Function.identity());
        for (TraceExitToolInfoVo traceExitToolInfoVo : goReturn) {
            TraceTool traceTool = tool2Rid.get(traceExitToolInfoVo.getRid());
            TraceExitRecordDetail exitRecordDetail = new TraceExitRecordDetail();
            exitRecordDetail.setId(IdGenUtils.genId());
            exitRecordDetail.setTrlId(exitRecordDetail.getId());
            exitRecordDetail.setExitRecordId(exitRecord.getId());
            exitRecordDetail.setReturnPnum(exitRecord.getReturnPnum());
            exitRecordDetail.setRid(traceTool.getRid());
            exitRecordDetail.setPartno(traceTool.getPartno());
            exitRecordDetail.setSerialno(traceTool.getTrno());
            exitRecordDetail.setRemark(traceExitToolInfoVo.getRemark());
            exitRecordDetail.setWorkorderno("9527");
            exitRecordDetail.setNum("");
            exitRecordDetail.setTpNo("");
            exitRecordDetail.setIssueRid(traceTool.getIssueRid());
            exitRecordDetail.setTlFlag(traceTool.getTlFlag());
            exitRecordDetail.setUnitofmeas(traceTool.getUnitofmeas());
            exitRecordDetail.setBarcode(traceTool.getBarcode());
            exitRecordDetail.setRfidId(traceTool.getRfidId());
            exitRecordDetail.setParentPartno(traceTool.getParentPartno());
            exitRecordDetail.setParentTrno(traceTool.getParentTrno());
            exitRecordDetail.setParent(traceTool.getParent());
            exitRecordDetail.setWhseDesc(traceTool.getWhseDesc());
            exitRecordDetail.setStation("CAN");
            exitRecordDetail.setAlternatePartno("");
            exitRecordDetail.setStoresloc(traceTool.getStoresloc());
            exitRecordDetail.setWarehouse(traceTool.getWarehouse());
            exitRecordDetail.setChildNum(ObjectUtil.isEmpty(traceTool.getChildNum()) ? null : StrUtil.toString(traceTool.getChildNum()));
            exitRecordDetail.setMeasuringNo(traceTool.getMeasuringNo());
            exitRecordDetail.setStandByPn(traceTool.getStandByPn());
            exitRecordDetail.setPartdescr(traceTool.getPartdescr());
            exitRecordDetail.setCatalogueType(traceTool.getCatalogueType());
            exitRecordDetail.setTlStatus(traceTool.getTlStatus());
            exitRecordDetail.setCreateTime(LocalDateTime.now());
            exitRecordDetails.add(exitRecordDetail);
        }
        this.save(exitRecord);
        recordDetailService.saveBatch(exitRecordDetails, 500);
        return CommonResp.buildSuccessMsg("生成退料单成功!");
    }

    @Override
    public CommonResp getGoTlReturn(String returnPnum, String createUser, String created, String status, String origin, String type) {
        List<TraceToolExitInfoVo> traceToolExitInfos = new ArrayList<>();
        List<TraceExitRecord> list = list(Wrappers.<TraceExitRecord>lambdaQuery()
                .eq(StrUtil.isNotEmpty(returnPnum), TraceExitRecord::getReturnPnum, returnPnum)
                .eq(StrUtil.isNotEmpty(createUser), TraceExitRecord::getCreateUserCode, createUser)
                .eq(StrUtil.isNotEmpty(created), TraceExitRecord::getCreated, created)
                .eq(StrUtil.isNotEmpty(status), TraceExitRecord::getStatus, status)
                .eq(StrUtil.isNotEmpty(origin), TraceExitRecord::getOrigin, origin)
                .eq(StrUtil.isNotEmpty(type), TraceExitRecord::getWarehouse, type)
        );

        for (TraceExitRecord traceExitRecord : list) {
            TraceToolExitInfoVo traceToolExitInfo = new TraceToolExitInfoVo();
            traceToolExitInfo.setStatus(traceExitRecord.getStatus());
            traceToolExitInfo.setRemark(traceExitRecord.getReturnRemark());
            traceToolExitInfo.setUpdated(ObjectUtil.isEmpty(traceExitRecord.getUpdated()) ? null : LocalDateTimeUtil.format(traceExitRecord.getCreated(), "yyyy-MM-dd HH:mm:ss"));
            traceToolExitInfo.setCreated(LocalDateTimeUtil.format(traceExitRecord.getCreated(), "yyyy-MM-dd HH:mm:ss"));
            traceToolExitInfo.setOrigin(traceExitRecord.getOrigin());
            traceToolExitInfo.setUpdatedUser(ObjectUtil.isEmpty(traceExitRecord.getUpdateUserCode()) ? null : traceExitRecord.getUpdateUserCode() + " " + traceExitRecord.getUpdateUserName());
            traceToolExitInfo.setType(traceExitRecord.getWarehouse());
            traceToolExitInfo.setCreatedUser(StrUtil.format("{} {}", traceExitRecord.getCreateUserCode(), traceExitRecord.getCreateUserName()));
            traceToolExitInfo.setReturnPnum(traceExitRecord.getReturnPnum());
            traceToolExitInfos.add(traceToolExitInfo);
        }

        return CommonResp.buildSucsDataListMsg(traceToolExitInfos, "数据获取成功！");
    }

    @Override
    public CommonResp getTlReturnList(String returnPnum) {
        List<TraceExitRecordDetail> exitRecordDetails = recordDetailService.list(Wrappers.<TraceExitRecordDetail>lambdaQuery().eq(TraceExitRecordDetail::getReturnPnum, returnPnum));
        if (CollUtil.isNotEmpty(exitRecordDetails)) {
            return CommonResp.buildSucsDataListMsg(exitRecordDetails, "数据获取成功！");
        } else {
            return CommonResp.buildFailMsg("没有该退料单信息");
        }
    }
}
